home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / DOG.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  9KB  |  365 lines

  1. /*    SCCS Id: @(#)dog.c    3.0    89/11/20
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "edog.h"
  7.  
  8. #ifdef OVLB
  9.  
  10. char NEARDATA dogname[63] = DUMMY;
  11. char NEARDATA catname[63] = DUMMY;
  12.  
  13. #endif /* OVLB */
  14.  
  15. #define domestic(mtmp)    (mtmp->data->msound == MS_BARK || mtmp->data->msound == MS_MEW)
  16.  
  17. #ifdef OVLB
  18.  
  19. void
  20. initedog(mtmp)
  21. register struct monst *mtmp;
  22. {
  23.     mtmp->mtame = domestic(mtmp) ? 10 : 5;
  24.     mtmp->mpeaceful = 1;
  25.     mtmp->mleashed = 0;
  26.     mtmp->meating = 0;
  27.     EDOG(mtmp)->droptime = 0;
  28.     EDOG(mtmp)->dropdist = 10000;
  29.     EDOG(mtmp)->apport = 10;
  30.     EDOG(mtmp)->whistletime = 0;
  31.     EDOG(mtmp)->hungrytime = 1000 + moves;
  32. }
  33.  
  34. void
  35. make_familiar(otmp)
  36. register struct obj *otmp;
  37. {
  38.     register struct monst *mtmp;
  39.     register struct permonst *pm;
  40.  
  41. top:
  42.     if (otmp) pm = &mons[otmp->corpsenm]; /* Figurine; otherwise spell */
  43.     else if (rn2(3)) {
  44.         if (!(pm = rndmonst())) {
  45.         pline("There seems to be nothing available for a familiar.");
  46.         return;
  47.         }
  48.     }
  49.     else if ((pl_character[0]=='W' || rn2(2)) && pl_character[0]!='C')
  50.         pm = &mons[PM_KITTEN];
  51.     else pm = &mons[PM_LITTLE_DOG];
  52.  
  53.     pm->pxlth += sizeof(struct edog);
  54.     mtmp = makemon(pm, u.ux, u.uy);
  55.     pm->pxlth -= sizeof(struct edog);
  56.     if (!mtmp) { /* monster was genocided */
  57.         if (otmp)
  58.         pline("The figurine writhes and then shatters into pieces!");
  59.         else goto top;
  60.         /* rndmonst() returns something not genocided always, so this
  61.          * means it was a cat or dog; loop back to try again until
  62.          * either rndmonst() is called, or if only one of cat/dog
  63.          * was genocided, they get the other.
  64.          */
  65.         return;
  66.     }
  67.     initedog(mtmp);
  68.     mtmp->msleep = 0;
  69.     if (otmp && otmp->cursed) { /* cursed figurine */
  70.         You("get a bad feeling about this.");
  71.         mtmp->mtame = mtmp->mpeaceful = 0;
  72.     }
  73. }
  74.  
  75. struct monst *
  76. makedog() {
  77.     register struct monst *mtmp;
  78.     register char *petname;
  79.  
  80.     if (pl_character[0]=='C' || (pl_character[0] != 'W' && rn2(2))) {
  81.         mons[PM_LITTLE_DOG].pxlth = sizeof(struct edog);
  82.         mtmp = makemon(&mons[PM_LITTLE_DOG], u.ux, u.uy);
  83.         mons[PM_LITTLE_DOG].pxlth = 0;
  84.         petname = dogname;
  85.     } else {
  86.         mons[PM_KITTEN].pxlth = sizeof(struct edog);
  87.         mtmp = makemon(&mons[PM_KITTEN], u.ux, u.uy);
  88.         mons[PM_KITTEN].pxlth = 0;
  89.         petname = catname;
  90.     }
  91.  
  92.     if(!mtmp) return((struct monst *) 0); /* dogs were genocided */
  93.  
  94.     if (petname[0]) {
  95.         mtmp = christen_monst(mtmp, petname);
  96. #ifndef MACOS
  97.         petname[0] = '\0'; /* name first only; actually unnecessary */
  98. #endif
  99.     }
  100.     initedog(mtmp);
  101.     return(mtmp);
  102. }
  103.  
  104. /* attach the monsters that went down (or up) together with @ */
  105. struct monst *mydogs = 0;
  106. /* monsters that fell through a trap door or stepped on a tele-trap. */
  107. /* 'down' is now true only of trap door falling, not for tele-trap. */
  108. struct monst *fallen_down = 0;
  109.                 
  110. void
  111. losedogs(){
  112.     register struct monst *mtmp,*mtmp0,*mtmp2;
  113.  
  114.     while(mtmp = mydogs){
  115.         mydogs = mtmp->nmon;
  116.         mtmp->nmon = fmon;
  117.         fmon = mtmp;
  118.         mnexto(mtmp);
  119.     }
  120. #if defined(LINT) || defined(__GNULINT__)
  121.     mtmp0 = (struct monst *)0;
  122. #endif
  123.     for(mtmp = fallen_down; mtmp; mtmp = mtmp2) {
  124.         mtmp2 = mtmp->nmon;
  125.         if(mtmp->mx == dlevel) {
  126.             mtmp->mx = 0;
  127.             if(mtmp == fallen_down)
  128.             fallen_down = mtmp->nmon;
  129.             else
  130.             mtmp0->nmon = mtmp->nmon;
  131.             mtmp->nmon = fmon;
  132.             fmon = mtmp;
  133.             if ((mtmp->data->geno&G_GENOD) && !(mtmp->data->geno&G_UNIQ)) {
  134. #ifdef KOPS
  135.             allow_kops = FALSE;
  136. #endif
  137.             mondead(mtmp);    /* must put in fmon list first */
  138. #ifdef KOPS
  139.             allow_kops = TRUE;
  140. #endif
  141.             } else if (mtmp->isshk)
  142.             home_shk(mtmp);
  143.             else
  144.             rloc(mtmp);
  145.         } else
  146.             mtmp0 = mtmp;
  147.     }
  148. }
  149.  
  150. #endif /* OVLB */
  151. #ifdef OVL2
  152.  
  153. void
  154. keepdogs(){
  155. register struct monst *mtmp;
  156.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  157.         if(((monnear(mtmp, u.ux, u.uy) && levl_follower(mtmp)) ||
  158.         /* the wiz will level t-port from anywhere to chase
  159.            the amulet; if you don't have it, will chase you
  160.            only if in range. -3. */
  161.             (u.uhave_amulet && mtmp->iswiz))
  162.             && !mtmp->msleep && mtmp->mcanmove) {
  163. #ifdef WORM
  164.         /* Bug "fix" for worm changing levels collapsing dungeon
  165.          */
  166.         if (mtmp->data == &mons[PM_LONG_WORM]) {
  167.             if (showmon(mtmp))
  168.                 pline("The worm can't fit down the stairwell.");
  169. # ifdef WALKIES
  170.             if (mtmp->mleashed) {
  171.                 pline("The leash slides off the slimy worm.");
  172.                 m_unleash(mtmp);
  173.             }
  174. # endif
  175.             continue;
  176.         }
  177. #endif
  178.         if (mon_has_amulet(mtmp)) {
  179.             pline("%s seems very disoriented for a moment.",
  180.                 Monnam(mtmp));
  181. #ifdef WALKIES
  182.             if (mtmp->mleashed) {
  183.                 pline("%s leash suddenly comes loose.",
  184.                     is_female(mtmp) ? "Her" :
  185.                     humanoid(mtmp->data) ? "His" : "Its");
  186.                 m_unleash(mtmp);
  187.             }
  188. #endif
  189.             continue;
  190.         }
  191.         relmon(mtmp);
  192.         mtmp->mx = mtmp->my = 0; /* avoid mnexto()/MON_AT() problem */
  193.         mtmp->nmon = mydogs;
  194.         mydogs = mtmp;
  195.         unpmon(mtmp);
  196.         keepdogs();    /* we destroyed the link, so use recursion */
  197.         return;        /* (admittedly somewhat primitive) */
  198.     }
  199. }
  200.  
  201. #endif /* OVL2 */
  202. #ifdef OVLB
  203.  
  204. void
  205. fall_down(mtmp, tolev) 
  206. register struct monst *mtmp; 
  207. register int tolev;
  208. {
  209.     relmon(mtmp);
  210.     mtmp->nmon = fallen_down;
  211.     fallen_down = mtmp;
  212. #ifdef WALKIES
  213.     if (mtmp->mleashed)  {
  214.         pline("The leash comes off!");
  215.         m_unleash(mtmp);
  216.     }
  217. #endif
  218.     unpmon(mtmp);
  219.     mtmp->mtame = 0;
  220.     mtmp->mx = tolev; 
  221.     mtmp->my = 0;
  222.         /* make sure to reset mtmp->mx to 0 when releasing, */
  223.         /* so rloc() on next level doesn't affect MON_AT() state */
  224. }
  225.  
  226. #endif /* OVLB */
  227. #ifdef OVL1
  228.  
  229. /* return quality of food; the lower the better */
  230. /* fungi will eat even tainted food */
  231. int
  232. dogfood(mon,obj)
  233. struct monst *mon;
  234. register struct obj *obj;
  235. {
  236.     boolean carni = carnivorous(mon->data);
  237.     boolean herbi = herbivorous(mon->data);
  238.  
  239.     switch(obj->olet) {
  240.     case FOOD_SYM:
  241.         if (obj->otyp == CORPSE && obj->corpsenm == PM_COCKATRICE &&
  242.         !resists_ston(mon->data))
  243.             return TABU;
  244.  
  245.         if (!carni && !herbi)
  246.             return (obj->cursed ? UNDEF : APPORT);
  247.  
  248.         switch (obj->otyp) {
  249.         case TRIPE_RATION:
  250.             return (carni ? DOGFOOD : MANFOOD);
  251.         case EGG:
  252.             if (obj->corpsenm == PM_COCKATRICE &&
  253.                         !resists_ston(mon->data))
  254.             return POISON;
  255.             return (carni ? CADAVER : MANFOOD);
  256.         case CORPSE:
  257.             if ((obj->age+50 <= monstermoves
  258.                         && obj->corpsenm != PM_LIZARD
  259.                         && mon->data->mlet != S_FUNGUS) ||
  260.             (acidic(&mons[obj->corpsenm]) &&
  261.                         !resists_acid(mon->data)) ||
  262.             (poisonous(&mons[obj->corpsenm]) &&
  263.                         !resists_poison(mon->data)))
  264.             return POISON;
  265.             else if (mon->data->mlet == S_FUNGUS)
  266.             return (herbi ? CADAVER : MANFOOD);
  267.             else return (carni ? CADAVER : MANFOOD);
  268.         case CLOVE_OF_GARLIC:
  269.             return (is_undead(mon->data) ? TABU :
  270.                 (herbi ? ACCFOOD : MANFOOD));
  271.         case TIN:
  272.             return MANFOOD;
  273.         case APPLE:
  274.         case CARROT:
  275.             return (herbi ? DOGFOOD : MANFOOD);
  276.         default:
  277. #ifdef TUTTI_FRUTTI
  278.             return (obj->otyp > SLIME_MOLD ?
  279. #else
  280.             return (obj->otyp > CLOVE_OF_GARLIC ?
  281. #endif
  282.                 (carni ? ACCFOOD : MANFOOD) :
  283.                 (herbi ? ACCFOOD : MANFOOD));
  284.         }
  285.     default:
  286.         if(!obj->cursed) return(APPORT);
  287.         /* fall into next case */
  288.     case BALL_SYM:
  289.     case CHAIN_SYM:
  290.     case ROCK_SYM:
  291.         return(UNDEF);
  292.     }
  293. }
  294.  
  295. #endif /* OVL1 */
  296. #ifdef OVL0
  297.  
  298. /* return roomnumber or -1 */
  299. int
  300. inroom(x,y) xchar x,y; {
  301.     register struct mkroom *croom = &rooms[0];
  302.     while(croom->hx >= 0){
  303.         if(croom->hx >= x-1 && croom->lx <= x+1 &&
  304.            croom->hy >= y-1 && croom->ly <= y+1)
  305.             return(croom - rooms);
  306.         croom++;
  307.     }
  308.     return(-1);    /* not in room or on door */
  309. }
  310.  
  311. #endif /* OVL0 */
  312. #ifdef OVLB
  313.  
  314. struct monst *
  315. tamedog(mtmp, obj)
  316. register struct monst *mtmp;
  317. register struct obj *obj;
  318. {
  319.     register struct monst *mtmp2;
  320.  
  321.     /* The wiz and medusa aren't even made peaceful. */
  322.     if (mtmp->iswiz
  323. #ifdef MEDUSA
  324.                || mtmp->data == &mons[PM_MEDUSA]
  325. #endif
  326.                                 )
  327.         return((struct monst *)0);
  328.  
  329.     /* worst case, at least he'll be peaceful. */
  330.     mtmp->mpeaceful = 1;
  331.     if(flags.moonphase == FULL_MOON && night() && rn2(6) && obj
  332.                         && mtmp->data->mlet == S_DOG)
  333.         return((struct monst *)0);
  334.  
  335.     /* If we cannot tame him, at least he's no longer afraid. */
  336.     mtmp->mflee = 0;
  337.     mtmp->mfleetim = 0;
  338.     if(mtmp->mtame || !mtmp->mcanmove ||
  339.        mtmp->isshk || mtmp->isgd ||
  340. #if defined(ALTARS) && defined(THEOLOGY)
  341.        mtmp->ispriest ||
  342. #endif
  343. #ifdef POLYSELF
  344.        is_human(mtmp->data) || (is_demon(mtmp->data) && !is_demon(uasmon)))
  345. #else
  346.        is_human(mtmp->data) || is_demon(mtmp->data))
  347. #endif
  348.         return((struct monst *)0);
  349.     if(obj) {
  350.         if(dogfood(mtmp, obj) >= MANFOOD) return((struct monst *)0);
  351.         if(cansee(mtmp->mx,mtmp->my))
  352.             pline("%s devours the %s.", Monnam(mtmp), xname(obj));
  353.         obfree(obj, (struct obj *)0);
  354.     }
  355.     mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
  356.     *mtmp2 = *mtmp;
  357.     mtmp2->mxlth = sizeof(struct edog);
  358.     if(mtmp->mnamelth) Strcpy(NAME(mtmp2), NAME(mtmp));
  359.     initedog(mtmp2);
  360.     replmon(mtmp,mtmp2);
  361.     return(mtmp2);
  362. }
  363.  
  364. #endif /* OVLB */
  365.